/******************************************
 * TP1 - Grupo
 *
 * test_bigfloat.cpp
 *
 * Tests para la clase BigFloat
 *
 ******************************************/

#include <iostream>
#include <stdlib.h>
#include "bigfloat.h"
#include <cstdio>
#include <cstdlib>
#include <cassert>

using namespace std;


void testBasico() {

    int i;
    short a[20];
    short b[20];
    //a[0] = 1;
    for(i=0; i<20; i++){
        a[i] = 0;
    }
    b[0] = 1;
    for(i=1; i<20; i++){
        b[i] = 0;
    }

    BigFloat n1(20, false, a, 6);
    BigFloat n2(20, true, b, 1);
    n1.asegurar("+0,00000000000000000000 x 10e0");
    n2.asegurar("-0,10000000000000000000 x 10e1");
    n1.sumar(n2);
    n1.asegurar("-0,10000000000000000000 x 10e1");
    cout << "OK 1" << endl;
}


void testCarry() {

    int i;
    short a[20], b[20];
    a[0] = 9;
    for(i=1; i<19; i++){
        a[i] = 0;
    }
    a[19] = 9;
    b[0] = 3;
    for(i=1; i<19; i++){
        b[i] = 0;
    }
    b[19] = 5;

    BigFloat n1(20, false, a, 13);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("+0,90000000000000000009 x 10e13");
    n2.asegurar("+0,30000000000000000005 x 10e13");
    n1.sumar(n2);
    n1.asegurar("+0,12000000000000000001 x 10e14");
    cout << "OK 1" << endl;

}

void testDosNegativos() {

    int i;
    short a[20], b[20];
    a[0] = 9;
    for(i=1; i<19; i++){
        a[i] = 0;
    }
    a[5] = 6;
    a[19] = 9;
    b[0] = 3;
    for(i=1; i<19; i++){
        b[i] = 0;
    }
    b[6] = 7;
    b[19] = 5;

    BigFloat n1(20, true, a, 13);
    BigFloat n2(20, true, b, 13);
    n1.asegurar("-0,90000600000000000009 x 10e13");
    n2.asegurar("-0,30000070000000000005 x 10e13");
    n1.sumar(n2);
    n1.asegurar("-0,12000067000000000001 x 10e14");
    cout << "OK 1" << endl;

}

void testResta1() {

    int i;
    short a[20], b[20];
    a[0] = 2;
    a[1] = 3;
    for(i=2; i<20; i++){
    a[i] = 0;
    }
    b[0] = 1;
    b[1] = 8;
    for(i=2; i<20; i++){
    b[i] = 0;
    }

    BigFloat n1(20, false, a, 13);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("+0,23000000000000000000 x 10e13");
    n2.asegurar("+0,18000000000000000000 x 10e13");
    n1.restar(n2);
    n1.asegurar("+0,50000000000000000000 x 10e12");
    cout << "OK 1" << endl;

    BigFloat n3(20, true, a, 13);
    n3.asegurar("-0,23000000000000000000 x 10e13");
    n2.asegurar("+0,18000000000000000000 x 10e13");
    n3.sumar(n2);
    n3.asegurar("-0,50000000000000000000 x 10e12");
    cout << "OK 2" << endl;

}


void testResta2() {

    int i;
    short a[20], b[20];
    a[0] = 2;
    a[1] = 3;
    for(i=2; i<19; i++){
        a[i] = 0;
    }
    a[5] = 6;
    a[19] = 4;
    b[0] = 1;
    b[1] = 8;
    for(i=2; i<19; i++){
        b[i] = 0;
    }
    b[6] = 7;
    b[19] = 9;

    BigFloat n1(20, false, a, 13);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("+0,23000600000000000004 x 10e13");
    n2.asegurar("+0,18000070000000000009 x 10e13");
    n1.restar(n2);
    n1.asegurar("+0,50005299999999999950 x 10e12");
    cout << "OK 1" << endl;

    BigFloat n3(20, true, a, 13);
    n3.asegurar("-0,23000600000000000004 x 10e13");
    n2.asegurar("+0,18000070000000000009 x 10e13");
    n3.sumar(n2);
    n3.asegurar("-0,50005299999999999950 x 10e12");
    cout << "OK 2" << endl;

}

void testResta3() {

    int i;
    short a[20], b[20];
    a[0] = 2;
    a[1] = 2;
    a[2] = 3;
    for(i=3; i<19; i++){
    a[i] = 0;
    }
    a[5] = 6;
    a[19] = 4;
    b[0] = 2;
    b[1] = 1;
    b[2] = 8;
    for(i=3; i<19; i++){
        b[i] = 0;
    }
    b[6] = 7;
    b[19] = 9;

    BigFloat n1(20, false, a, 20);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("+0,22300600000000000004 x 10e20");
    n2.asegurar("+0,21800070000000000009 x 10e13");
    n1.restar(n2);
    n1.asegurar("+0,22300597819993000004 x 10e20");
    cout << "OK 1" << endl;

    BigFloat n3(20, true, a, 20);
    n3.asegurar("-0,22300600000000000004 x 10e20");
    n2.asegurar("+0,21800070000000000009 x 10e13");
    n3.sumar(n2);
    n3.asegurar("-0,22300597819993000004 x 10e20");
    cout << "OK 2" << endl;

}

void testMultiplicar() {

    int i;
    short a[20], b[20];
    a[0] = 2;
    a[1] = 3;
    for(i=2; i<19; i++){
    a[i] = 0;
    }
    a[5] = 6;
    a[19] = 4;
    b[0] = 1;
    b[1] = 8;
    for(i=2; i<19; i++){
        b[i] = 0;
    }
    b[6] = 7;
    b[19] = 9;

    BigFloat n1(20, false, a, 20);
    BigFloat n2(20, true, b, 13);
    n1.asegurar("+0,23000600000000000004 x 10e20");
    n2.asegurar("-0,18000070000000000009 x 10e13");
    n1.multiplicar(n2);
    n1.asegurar("-0,41401241004200000027 x 10e32");
    cout << "OK 1" << endl;

}


void testMultiplicar2() {

    int i;
    short a[20], b[20];
    a[0] = 9;
    for(i=1; i<19; i++){
    a[i] = 0;
    }
    a[19] = 9;
    b[0] = 3;
    for(i=1; i<19; i++){
        b[i] = 0;
    }
    b[19] = 5;

    BigFloat n1(20, true, a, -13);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("-0,90000000000000000009 x 10e-13");
    n2.asegurar("+0,30000000000000000005 x 10e13");
    n1.multiplicar(n2);
    n1.asegurar("-0,27000000000000000007 x 10e0");
    cout << "OK 1" << endl;

}

void testMultiplicar3() {

    int i;
    short a[1], b[1];

    a[0]=3;
    //a[1]=2;
    b[0]=2;
    //b[1]=1;

    BigFloat n1(1, true, a, -13);
    BigFloat n2(1, false, b, 13);
    n1.asegurar("-0,3 x 10e-13");
    n2.asegurar("+0,2 x 10e13");
    n1.multiplicar(n2);
    n1.asegurar("-0,6 x 10e-1");
    cout << "OK 1" << endl;

}

void testMultiplicar4() {

    int i;
    short a[20], b[20];
    for(i=0; i<20; i++){
        a[i] = 0;
    }
    b[0] = 3;
    for(i=1; i<19; i++){
        b[i] = 0;
    }
    b[19] = 5;

    BigFloat n1(20, true, a, -13);
    BigFloat n2(20, false, b, 13);
    n1.asegurar("-0,00000000000000000000 x 10e0");
    n2.asegurar("+0,30000000000000000005 x 10e13");
    n1.multiplicar(n2);
    n1.asegurar("-0,00000000000000000000 x 10e0");
    cout << "OK 1" << endl;
    BigFloat n3(20, false, a, 26);
    n3.asegurar("+0,00000000000000000000 x 10e0");
    n2.multiplicar(n3);
    n2.asegurar("+0,00000000000000000000 x 10e0");
    cout << "OK 2" << endl;
}

void testRazon() {

    int i;
    short a[20], b[20];
    a[0] = 9;
    a[1] = 5;
    for(i=2; i<20; i++){
        a[i] = 0;
    }
    a[6] = 4;
    a[9] = 9;
    a[16] = 3;
    b[0] = 3;
    b[1] = 7;
    for(i=2; i<20; i++){
        b[i] = 0;
    }
    b[6] = 4;
    b[9] = 5;
    b[18] = 7;
    BigFloat n1(20, true, a, 13);
    BigFloat n2(20, false, b, 8);
    n1.asegurar("-0,95000040090000003000 x 10e13");
    n2.asegurar("+0,37000040050000000070 x 10e8");
    int res = BigFloat::razon(n1,n2);
    if(res != 256756){
        cerr << "La razon es " << res << "   cuando deberia ser 25675658718" << endl;
        assert(false);
    }
    cout << "OK 1" << endl;

}


void testDouble() {

    double d1 = 333.3393322222222;
    double d2 = 32425.44322222999;
    double d3 = 45616.30000000000;
   double d4 =  0.0000032425443999;
    double d5 = 0.4000000000000001;

    cout << "Double 1: ";
    printf("%3.13lf\n", d1);
    BigFloat n1(20, d1);
    cout << "BigFloat 1: " << n1 << endl;
    cout << "Double 2: ";
    printf("%5.11lf\n", d2);
    BigFloat n2(20, d2);
    cout << "BigFloat 2: " << n2 << endl;
    cout << "Double 3: ";
    printf("%5.11lf\n", d3);
    BigFloat n3(20, d3);
    cout << "BigFloat 3: " << n3 << endl;
    cout << "\n";
    cout << "Double 4: ";
    printf("%3.16lf\n", d4);
    BigFloat n4(20, d4);
    cout << "BigFloat 4: " << n4 << endl;
    cout << "Double 5: ";
    printf("%3.16lf\n", d5);
    BigFloat n5(20, d5);
    cout << "BigFloat 5: " << n5 << endl;
}


int main() {

    cout << "\nEjecucion de todos los test:" << endl;
    cerr << "\nTest basico de BigFloat -------------------------------------------------" << endl;
    testBasico();
    cerr << "\nTest del carry de BigFloat ----------------------------------------------" << endl;
    testCarry();
    cerr << "\nTest de la suma de BigFloat negativos -----------------------------------" << endl;
    testDosNegativos();
    cerr << "\nTest de la resta de BigFloat 1 ------------------------------------------" << endl;
    testResta1();
    cerr << "\nTest de la resta de BigFloat 2 ------------------------------------------" << endl;
    testResta2();
    cerr << "\nTest de la resta de BigFloat 3 ------------------------------------------" << endl;
    testResta3();
    cerr << "\nTest de la multiplicancion de BigFloat 1 --------------------------------" << endl;
    testMultiplicar();
    cerr << "\nTest de la multiplicancion de BigFloat 2 --------------------------------" << endl;
    testMultiplicar2();
    cerr << "\nTest de la multiplicancion de BigFloat 3 --------------------------------" << endl;
    testMultiplicar3();
    cerr << "\nTest de la multiplicancion de BigFloat 4 --------------------------------" << endl;
    testMultiplicar4();
    cerr << "\nTest de la razon de BigFloat --------------------------------------------" << endl;
    testRazon();
    cerr << "\nTest de construir un BigFloat con un double -----------------------------" << endl;
    testDouble();

// 	cerr << "\nTest dinamico de Big Float ----------------------------------------------" << endl;
// 	testDinamico();

    cerr << "\nBigFloat: OK\n" << endl;

    return 0;

}

